"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const date_1 = require("./describers/date");
const hour_1 = require("./describers/hour");
const minute_1 = require("./describers/minute");
const month_1 = require("./describers/month");
const week_1 = require("./describers/week");
function numberthize(num) {
    const n = parseInt(num);
    switch (20 < n ? n % 10 : n) {
        case 1:
            return num + "st";
        case 2:
            return num + "nd";
        case 3:
            return num + "rd";
        default:
            return num + "th";
    }
}
function segmentDesc(exp, meaning, n, r) {
    if ("*" === exp) {
        return "every " + meaning;
    }
    else {
        return function (e, t, n, r) {
            let o = e.match(/\d+|./g).map(function (e) {
                const t = Number(e);
                return isNaN(t) ? e : t;
            });
            const a = o[0];
            if (Number.isInteger(a)) {
                if (1 === o.length)
                    return "" + (n[a] || a); // 2 =？ 二月
                if (3 === o.length && "/" === o[1] && Number.isInteger(o[2]))
                    return "每隔" + numberthize(o[2]) + " " + t + " from " + (n[a] || a) + " through " + (n[r] || r);
                if (3 === o.length && "-" === o[1] && Number.isInteger(o[2]) && o[2] >= a)
                    return "every " + t + " from " + (n[a] || a) + " through " + (n[o[2]] || o[2]);
                if (5 === o.length && "-" === o[1] && Number.isInteger(o[2]) && o[2] >= a && "/" === o[3] && Number.isInteger(o[4]) && 1 <= o[4])
                    return "every " + numberthize(o[4]) + " " + t + " from " + (n[a] || a) + " through " + (n[o[2]] || o[2]);
            }
            else if (3 === o.length && "/" === o[1] && Number.isInteger(o[2]) && "*" === o[0])
                return "每" + `${o[2]}个` + t;
            return "";
        }(exp, meaning, n, r);
    }
}
function expandPartToDesc(seg, meaning, n, maxValue, o = null) {
    const group = seg.split(",");
    const smallSeg = group.map(function (exp) {
        return segmentDesc(exp, meaning, n, maxValue);
    });
    return ((o ? "" : meaning + " ") + function (e) {
        switch (e.length) {
            case 0:
                return "";
            case 1:
                return e[0];
            case 2:
                return e[0] + "和" + e[1];
            default:
                return e.slice(0, e.length - 1).join(", ") + ", 和 " + e[e.length - 1];
        }
    }(smallSeg))
        .replace("every 1st", "every")
        .replace(meaning + " every", "every")
        .replace(", " + meaning, ", ")
        .replace(", and " + meaning, ", and ");
}
const oneOrTwoDigitsReg = /^0*\d\d?$/;
exports.describeCrontab = function (e) {
    const parts = e.parts;
    const minuteSeg = parts[0];
    const hourSeg = parts[1];
    const daySeg = parts[2];
    const monthSeg = parts[3];
    const weekSeg = parts[4];
    let dayDesc;
    if ("*" === daySeg) {
        dayDesc = "";
    }
    else {
        dayDesc = new date_1.DatePartDescriber(daySeg).describe();
    }
    const monthDesc = monthSeg === '*' ? '' : new month_1.MonthPartDescriber(monthSeg).describe();
    const weekDesc = "*" === weekSeg ? "" : new week_1.WeekPartDescriber(weekSeg).describe();
    const daysAndWeeks = weekSeg.indexOf('*') === 0 || weekSeg.indexOf('*') === 0;
    const minutesDesc = new minute_1.MinutePartDescriber(minuteSeg).describe();
    const hourDesc = "*" === hourSeg ? "" : new hour_1.HourPartDescriber(hourSeg).describe();
    function fullDateWhenDaysOrWeeks(dayDesc, weekDesc, month) {
        if (dayDesc && weekDesc) {
            const d = `${dayDesc}`.trim();
            const w = `${month}的${weekDesc}`.trim();
            return `${d} 或者 ${w}`;
        }
        else {
            return dayDesc || weekDesc;
        }
    }
    function fullDateWhenDaysAndWeeks(dayDesc, weedDesc, monthDesc) {
        if (dayDesc && weedDesc) {
            return `${dayDesc}(并且是${weekDesc})`;
        }
        return dayDesc || weedDesc;
    }
    const dayFull = daysAndWeeks ?
        fullDateWhenDaysAndWeeks(dayDesc, weekDesc, monthDesc) :
        fullDateWhenDaysOrWeeks(dayDesc, weekDesc, monthDesc);
    let pre = '每';
    if (minutesDesc && !minutesDesc.startsWith('每')) {
        pre = '每小时 ';
    }
    if (hourDesc && !hourDesc.startsWith('每')) {
        pre = '每天 ';
    }
    if (dayDesc && !dayDesc.startsWith('每')) {
        pre = '每月 ';
    }
    if (weekDesc && !weekDesc.startsWith('每')) {
        pre = '每';
    }
    if (monthDesc && !monthDesc.startsWith('每')) {
        pre = '每年 ';
    }
    const descFull = `${monthDesc} ${dayFull} ${hourDesc} ${minutesDesc}`.trim()
        .replace(/\s{2,}/g, ' ');
    return {
        start: "At",
        minutes: minutesDesc || null,
        hours: hourDesc || null,
        isTime: true,
        dates: dayDesc || null,
        weekdays: weekDesc || null,
        months: monthDesc || null,
        end: ".",
        descFull,
        full: `${pre}${descFull}`
    };
};
